package org.jeecg.modules.oms.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.oms.dto.SemiProductSalesOrderWithTransactionsDTO;
import org.jeecg.modules.oms.entity.SemiProductSalesOrder;
import org.jeecg.modules.oms.entity.SemiProductSalesOrderDetail;
import org.jeecg.modules.oms.service.ISemiProductSalesOrderDetailService;
import org.jeecg.modules.oms.service.ISemiProductSalesOrderProgressService;
import org.jeecg.modules.oms.service.ISemiProductSalesOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.apache.shiro.SecurityUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

/**
 * 半成品销售订单Controller
 */
@Api(tags = "半成品销售订单管理")
@RestController
@RequestMapping("/oms/semiProductSalesOrder")
@Slf4j
public class SemiProductSalesOrderController extends JeecgController<SemiProductSalesOrder, ISemiProductSalesOrderService> {

    @Autowired
    private ISemiProductSalesOrderService semiProductSalesOrderService;
    
    @Autowired
    private ISemiProductSalesOrderDetailService detailService;
    
    @Autowired
    private ISemiProductSalesOrderProgressService progressService;

    /**
     * 分页列表查询
     */
    @AutoLog(value = "半成品销售订单-分页列表查询")
    @ApiOperation(value = "半成品销售订单-分页列表查询", notes = "半成品销售订单-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<SemiProductSalesOrder>> queryPageList(SemiProductSalesOrder semiProductSalesOrder,
                                                              @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                              @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                              HttpServletRequest req) {
        Page<SemiProductSalesOrder> page = new Page<SemiProductSalesOrder>(pageNo, pageSize);
        IPage<SemiProductSalesOrder> pageList = semiProductSalesOrderService.queryOrderPage(page, semiProductSalesOrder);
        return Result.OK(pageList);
    }

    /**
     * 添加
     */
    @AutoLog(value = "半成品销售订单-添加")
    @ApiOperation(value = "半成品销售订单-添加", notes = "半成品销售订单-添加")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody SemiProductSalesOrderWithTransactionsDTO orderDTO) {
        try {
            boolean result;
            if (orderDTO.getTransactionList() != null && !orderDTO.getTransactionList().isEmpty()) {
                // 如果包含交易记录，使用带交易记录的方法
                result = semiProductSalesOrderService.addSemiProductSalesOrderWithTransactions(orderDTO, orderDTO.getTransactionList());
            } else {
                // 否则使用普通方法
                result = semiProductSalesOrderService.addSemiProductSalesOrder(orderDTO);
            }
            
            if (result) {
                return Result.OK("添加成功！");
            } else {
                return Result.error("添加失败！");
            }
        } catch (Exception e) {
            log.error("添加半成品销售订单失败", e);
            return Result.error("添加失败：" + e.getMessage());
        }
    }

    /**
     * 编辑
     */
    @AutoLog(value = "半成品销售订单-编辑")
    @ApiOperation(value = "半成品销售订单-编辑", notes = "半成品销售订单-编辑")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody SemiProductSalesOrderWithTransactionsDTO orderDTO) {
        try {
            boolean result;
            if (orderDTO.getTransactionList() != null && !orderDTO.getTransactionList().isEmpty()) {
                // 如果包含交易记录，使用带交易记录的方法
                result = semiProductSalesOrderService.updateSemiProductSalesOrderWithTransactions(orderDTO, orderDTO.getTransactionList());
            } else {
                // 否则使用普通方法
                result = semiProductSalesOrderService.updateSemiProductSalesOrder(orderDTO);
            }
            
            if (result) {
                return Result.OK("编辑成功!");
            } else {
                return Result.error("编辑失败!");
            }
        } catch (Exception e) {
            log.error("编辑半成品销售订单失败", e);
            return Result.error("编辑失败：" + e.getMessage());
        }
    }

    /**
     * 通过id删除
     */
    @AutoLog(value = "半成品销售订单-通过id删除")
    @ApiOperation(value = "半成品销售订单-通过id删除", notes = "半成品销售订单-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        try {
            boolean result = semiProductSalesOrderService.deleteSemiProductSalesOrder(id);
            if (result) {
                return Result.OK("删除成功!");
            } else {
                return Result.error("删除失败!");
            }
        } catch (Exception e) {
            log.error("删除半成品销售订单失败", e);
            return Result.error("删除失败：" + e.getMessage());
        }
    }

    /**
     * 批量删除
     */
    @AutoLog(value = "半成品销售订单-批量删除")
    @ApiOperation(value = "半成品销售订单-批量删除", notes = "半成品销售订单-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        try {
            String[] idArray = ids.split(",");
            for (String id : idArray) {
                if (oConvertUtils.isNotEmpty(id)) {
                    semiProductSalesOrderService.deleteSemiProductSalesOrder(id);
                }
            }
            return Result.OK("批量删除成功!");
        } catch (Exception e) {
            log.error("批量删除半成品销售订单失败", e);
            return Result.error("批量删除失败：" + e.getMessage());
        }
    }

    /**
     * 通过id查询
     */
    @AutoLog(value = "半成品销售订单-通过id查询")
    @ApiOperation(value = "半成品销售订单-通过id查询", notes = "半成品销售订单-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<SemiProductSalesOrder> queryById(@RequestParam(name = "id", required = true) String id) {
        SemiProductSalesOrder semiProductSalesOrder = semiProductSalesOrderService.getById(id);
        if (semiProductSalesOrder == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(semiProductSalesOrder);
    }

    /**
     * 根据订单号查询
     */
    @AutoLog(value = "半成品销售订单-根据订单号查询")
    @ApiOperation(value = "半成品销售订单-根据订单号查询", notes = "半成品销售订单-根据订单号查询")
    @GetMapping(value = "/queryByOrderNo")
    public Result<SemiProductSalesOrder> queryByOrderNo(@RequestParam(name = "orderNo", required = true) String orderNo) {
        try {
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            Integer tenantId = null;
            if (loginUser != null && oConvertUtils.isNotEmpty(loginUser.getRelTenantIds())) {
                tenantId = Integer.parseInt(loginUser.getRelTenantIds().split(",")[0]);
            }
            
            SemiProductSalesOrder order = semiProductSalesOrderService.getByOrderNo(orderNo, tenantId);
            if (order == null) {
                return Result.error("未找到对应订单");
            }
            return Result.OK(order);
        } catch (Exception e) {
            log.error("根据订单号查询失败", e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }

    /**
     * 审核订单
     */
    @AutoLog(value = "半成品销售订单-审核")
    @ApiOperation(value = "半成品销售订单-审核", notes = "半成品销售订单-审核")
    @PostMapping(value = "/audit")
    public Result<String> auditOrder(@RequestParam(name = "id", required = true) String id,
                                    @RequestParam(name = "status", required = true) Integer status,
                                    @RequestParam(name = "auditRemark", required = false) String auditRemark) {
        try {
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String auditBy = loginUser != null ? loginUser.getUsername() : "system";
            
            boolean result = semiProductSalesOrderService.auditOrder(id, status, auditBy, auditRemark);
            if (result) {
                return Result.OK("审核成功!");
            } else {
                return Result.error("审核失败!");
            }
        } catch (Exception e) {
            log.error("审核订单失败", e);
            return Result.error("审核失败：" + e.getMessage());
        }
    }

    /**
     * 更新订单状态
     */
    @AutoLog(value = "半成品销售订单-更新状态")
    @ApiOperation(value = "半成品销售订单-更新状态", notes = "半成品销售订单-更新状态")
    @PostMapping(value = "/updateStatus")
    public Result<String> updateStatus(@RequestParam(name = "id", required = true) String id,
                                      @RequestParam(name = "status", required = true) Integer status) {
        try {
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String updateBy = loginUser != null ? loginUser.getUsername() : "system";
            
            boolean result = semiProductSalesOrderService.updateOrderStatus(id, status, updateBy);
            if (result) {
                return Result.OK("状态更新成功!");
            } else {
                return Result.error("状态更新失败!");
            }
        } catch (Exception e) {
            log.error("更新订单状态失败", e);
            return Result.error("状态更新失败：" + e.getMessage());
        }
    }

    /**
     * 检查订单号是否存在
     */
    @AutoLog(value = "半成品销售订单-检查订单号")
    @ApiOperation(value = "半成品销售订单-检查订单号", notes = "半成品销售订单-检查订单号")
    @GetMapping(value = "/checkOrderNo")
    public Result<Boolean> checkOrderNo(@RequestParam(name = "orderNo", required = true) String orderNo,
                                       @RequestParam(name = "excludeId", required = false) String excludeId) {
        try {
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            Integer tenantId = null;
            if (loginUser != null && oConvertUtils.isNotEmpty(loginUser.getRelTenantIds())) {
                tenantId = Integer.parseInt(loginUser.getRelTenantIds().split(",")[0]);
            }
            
            boolean exists = semiProductSalesOrderService.checkOrderNoExists(orderNo, tenantId, excludeId);
            return Result.OK(exists);
        } catch (Exception e) {
            log.error("检查订单号失败", e);
            return Result.error("检查失败：" + e.getMessage());
        }
    }

    /**
     * 生成订单编号
     */
    @AutoLog(value = "半成品销售订单-生成订单编号")
    @ApiOperation(value = "半成品销售订单-生成订单编号", notes = "半成品销售订单-生成订单编号")
    @GetMapping(value = "/generateOrderNo")
    public Result<String> generateOrderNo() {
        try {
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            Integer tenantId = null;
            if (loginUser != null && oConvertUtils.isNotEmpty(loginUser.getRelTenantIds())) {
                tenantId = Integer.parseInt(loginUser.getRelTenantIds().split(",")[0]);
            }
            
            String orderNo = semiProductSalesOrderService.generateOrderNo(tenantId);
            return Result.OK(orderNo);
        } catch (Exception e) {
            log.error("生成订单编号失败", e);
            return Result.error("生成失败：" + e.getMessage());
        }
    }

    /**
     * 计算订单利润
     */
    @AutoLog(value = "半成品销售订单-计算利润")
    @ApiOperation(value = "半成品销售订单-计算利润", notes = "半成品销售订单-计算利润")
    @GetMapping(value = "/calculateProfit")
    public Result<BigDecimal> calculateProfit(@RequestParam(name = "id", required = true) String id) {
        try {
            BigDecimal profit = semiProductSalesOrderService.calculateOrderProfit(id);
            return Result.OK(profit);
        } catch (Exception e) {
            log.error("计算订单利润失败", e);
            return Result.error("计算失败：" + e.getMessage());
        }
    }

    /**
     * 导出excel
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, SemiProductSalesOrder semiProductSalesOrder) {
        return super.exportXls(request, semiProductSalesOrder, SemiProductSalesOrder.class, "半成品销售订单");
    }

    /**
     * 通过excel导入数据
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, SemiProductSalesOrder.class);
    }

    /**
     * 获取订单明细列表
     */
    @AutoLog(value = "半成品销售订单-获取明细列表")
    @ApiOperation(value = "半成品销售订单-获取明细列表", notes = "半成品销售订单-获取明细列表")
    @GetMapping(value = "/getOrderDetails")
    public Result<List<SemiProductSalesOrderDetail>> getOrderDetails(@RequestParam(name = "orderId", required = true) String orderId) {
        try {
            List<SemiProductSalesOrderDetail> details = detailService.getByOrderId(orderId);
            return Result.OK(details);
        } catch (Exception e) {
            log.error("获取订单明细失败", e);
            return Result.error("获取明细失败：" + e.getMessage());
        }
    }

    /**
     * 保存订单明细
     */
    @AutoLog(value = "半成品销售订单-保存明细")
    @ApiOperation(value = "半成品销售订单-保存明细", notes = "半成品销售订单-保存明细")
    @PostMapping(value = "/saveOrderDetails")
    public Result<String> saveOrderDetails(@RequestParam(name = "orderId", required = true) String orderId,
                                          @RequestBody List<SemiProductSalesOrderDetail> details) {
        try {
            boolean result = detailService.saveOrderDetailBatch(orderId, details);
            if (result) {
                // 重新计算订单金额
                BigDecimal totalAmount = detailService.calculateTotalAmount(orderId);
                BigDecimal totalCost = detailService.calculateTotalCost(orderId);
                
                // 更新订单金额信息
                SemiProductSalesOrder order = semiProductSalesOrderService.getById(orderId);
                if (order != null) {
                    BigDecimal paidAmount = order.getPaidAmount() != null ? order.getPaidAmount() : BigDecimal.ZERO;
                    BigDecimal unpaidAmount = totalAmount.subtract(paidAmount);
                    Integer payStatus = paidAmount.compareTo(totalAmount) >= 0 ? 1 : 0;
                    
                    LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
                    String updateBy = loginUser != null ? loginUser.getUsername() : "system";
                    
                    semiProductSalesOrderService.updateOrderAmount(orderId, totalAmount, paidAmount, unpaidAmount, payStatus, updateBy);
                }
                
                return Result.OK("保存成功!");
            } else {
                return Result.error("保存失败!");
            }
        } catch (Exception e) {
            log.error("保存订单明细失败", e);
            return Result.error("保存失败：" + e.getMessage());
        }
    }
}
